package com.mamesoft.namibiamc.beans;

import com.mamesoft.namibiamc.tools.JDBC;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.ResultSet;
import hirondelle.date4j.DateTime;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.security.Security;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.faces.context.FacesContext;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.ServletContext;

public class RichiamaBean {

    private int minuti = 60;
    private boolean renderRichiama = true;
    private boolean renderRecidivi = true;
    private boolean renderTabellaRecidivi = false;
    private boolean renderTabellaRichiami = false;
    private boolean listaRichiamaVuota = false;
    private boolean listaRecidiciVuota = false;
    private String tastoRichiama = "VISUALIZZA";
    private String tastoRichiamaRecidivi = "VISUALIZZA";

    public void richiama() {
        if (!renderTabellaRichiami) {
            setTastoRichiama("INVIA");
            setRenderTabellaRichiami(true);
            listRichiami();
        } else {
            Connection c = null;
            boolean error = false;
            try {
                Timestamp t = new Timestamp(System.currentTimeMillis() + (minuti * 60 * 1000));
                c = JDBC.connect();

                String q = "SELECT id, email "
                        + "FROM ("
                        + "SELECT capo_villaggio "
                        + "FROM cartella "
                        + "JOIN paziente ON ( pid = paziente.id ) "
                        + "WHERE richiami =0 "
                        + "AND is_fatta =  'F' "
                        + "AND data < '"
                        + t + "' GROUP BY capo_villaggio "
                        + ") AS t "
                        + "JOIN paziente ON t.capo_villaggio = paziente.id";
                ResultSet set = JDBC.executeQuery(q, c);
                while (set.next()) {
                    int id = set.getInt("id");
                    String email = set.getString("email");
                    String q2 = "SELECT  pid, nome, cognome, data, richiami "
                            + "FROM cartella "
                            + "JOIN anagrafe ON pid = anagrafe.id "
                            + "JOIN paziente ON pid = paziente.id "
                            + "WHERE capo_villaggio ='" + id + "' "
                            + "AND richiami =  '0' "
                            + "AND is_fatta =  'F' "
                            + "AND data < '"
                            + t + "'";
                    ResultSet set2 = JDBC.executeQuery(q2, c);

                    LinkedList<Visita> l = new LinkedList<Visita>();
                    while (set2.next()) {
                        Visita v = new Visita();
                        v.setNome(set2.getString("nome"));
                        v.setCognome(set2.getString("cognome"));
                        DateTime h = new DateTime(set2.getTimestamp("data").toString());
                        v.setData(h.format("DD/MM/YYYY hh:mm:ss"));
                        l.add(v);
                    }
                    File txt = toTxt(l, id);
                    sendCapovillaggioMail(email, txt);
                    txt.delete();
                }


                String r = "SELECT DISTINCT pid,email FROM cartella "
                        + "JOIN paziente on cartella.pid = paziente.id "
                        + "WHERE  richiami = '0' "
                        + "AND is_fatta = 'F' "
                        + "AND data < '" + t + "';";
                set = JDBC.executeQuery(r, c);

                while (set.next()) {
                    int pid = set.getInt("pid");
                    String email = set.getString("email");
                    if (!email.equals("") && email != null) {
                        String q3 = "SELECT data,descrizione,tipo_visita,richiami "
                                + "FROM cartella WHERE richiami='0' "
                                + "AND is_fatta = 'F' "
                                + "AND data < '" + t + "' "
                                + "and pid = " + pid;
                        ResultSet set2 = JDBC.executeQuery(q3, c);
                        LinkedList<String> l = new LinkedList<String>();
                        while (set2.next()) {
                            DateTime d = new DateTime(set2.getTimestamp("data").toString());
                            String s = "DATA: " + d.format("DD/MM/YYYY hh:mm:ss") + "\n"
                                    + "DESCRIZIONE: " + set2.getString("descrizione") + "\n"
                                    + "TIPO VISITA: " + set2.getString("tipo_visita") + "\n"
                                    + "NUMERO RICHIAMO: " + (set2.getInt("richiami")+1) + "\n";
                            l.add(s);
                        }
                        sendMailRichiami(email, l);
                    }
                }
                r = "UPDATE cartella "
                        + "SET  richiami ='1' "
                        + "WHERE  richiami = '0' "
                        + "AND is_fatta = 'F' "
                        + "AND data < '" + t + "';";
                JDBC.executeStatement(r, c);
            } catch (Exception ex) {
                ex.printStackTrace();
                error = true;
            } finally {
                try {
                    c.close();
                } catch (Exception ex) {
                }
            }
            if (!error) {
                setRenderRichiama(false);
                setRenderTabellaRichiami(false);
            }
        }
    }

    private void sendMailRichiami(String mail, LinkedList<String> l) throws MessagingException {
        String textMessage = "email:" + mail + "\n\n\n\nCaro/a " + mail + "\n \n La informiamo che è richiamato "
                + "per le seguenti visite:\n\n";
        Iterator i = l.iterator();
        while (i.hasNext()) {
            String s = (String) i.next();
            textMessage += s + "\n";
        }

        textMessage += "Distinti Saluti \nIl team di NMC";

        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        // Get a Properties object
        Properties props = System.getProperties();
        props.setProperty("mail.smtp.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "false");
        final String user = "namibiamc@gmail.com";
        final String password = "muccamucca";
        Session session = Session.getDefaultInstance(props, new Authenticator() {

            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, password);
            }
        });
        // — Create a new message –
        Message msg = new MimeMessage(session);
        // — Set the FROM and TO fields – 
        msg.setFrom(new InternetAddress(user + ""));
        msg.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("simone.melchiori90@gmail.com", false));
        msg.setSubject("Namibia Medical Control: RICHIAMI VISITE");
        msg.setText(textMessage);
        msg.setSentDate(new Date());
        Transport.send(msg);
    }

    private void sendCapovillaggioMail(String mail, File txt) throws MessagingException {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        // Get a Properties object
        Properties props = System.getProperties();
        props.setProperty("mail.smtp.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "false");
        final String user = "namibiamc@gmail.com";
        final String password = "muccamucca";
        Session session = Session.getDefaultInstance(props, new Authenticator() {

            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, password);
            }
        });
        // — Create a new message –
        Message msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress(user + ""));
        msg.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("simone.melchiori90@gmail.com", false));
        msg.setSubject("Namibia Medical Control: Pazienti richiamati");
        msg.setSentDate(new Date());

        MimeBodyPart textPart = new MimeBodyPart();
        textPart.setText("email:" + mail + "\n\n\n\nCaro/a " + mail + "\n \n La informiamo che i seguenti pazienti "
                + "sono stati richiamati.\n"
                + "Vedi allegato!"
                + "\n\n"
                + "Distinti Saluti \n"
                + "Il team di NMC");

        MimeBodyPart attachFilePart = new MimeBodyPart();
        FileDataSource fds =
                new FileDataSource(txt);
        attachFilePart.setDataHandler(new DataHandler(fds));
        attachFilePart.setFileName(fds.getName());

        Multipart mp = new MimeMultipart();
        mp.addBodyPart(textPart);
        mp.addBodyPart(attachFilePart);

        msg.setContent(mp);

        Transport.send(msg);
    }

    public void richiamaRecidivi() {
        if (!renderTabellaRecidivi) {
            setTastoRichiamaRecidivi("INVIA");
            setRenderTabellaRecidivi(true);
            listReicidivi();
        } else {
            
            Connection c = null;
            boolean error = false;
    
            try {
                Timestamp t = new Timestamp(System.currentTimeMillis());
                c = JDBC.connect();
                
                String q = "SELECT id, email "
                        + "FROM ("
                        + "SELECT capo_villaggio "
                        + "FROM cartella "
                        + "JOIN paziente ON ( pid = paziente.id ) "
                        + "WHERE richiami !=0 "
                        + "AND is_fatta =  'F' "
                        + "AND data < '"
                        + t + "' GROUP BY capo_villaggio "
                        + ") AS t "
                        + "JOIN paziente ON t.capo_villaggio = paziente.id";
                ResultSet set = JDBC.executeQuery(q, c);
                while (set.next()) {
                    int id = set.getInt("id");
                    String email = set.getString("email");
                    String q2 = "SELECT  pid, nome, cognome, data, richiami "
                            + "FROM cartella "
                            + "JOIN anagrafe ON pid = anagrafe.id "
                            + "JOIN paziente ON pid = paziente.id "
                            + "WHERE capo_villaggio ='" + id + "' "
                            + "AND richiami !=  '0' "
                            + "AND is_fatta =  'F' "
                            + "AND data < '"
                            + t + "'";
                    ResultSet set2 = JDBC.executeQuery(q2, c);

                    LinkedList<Visita> l = new LinkedList<Visita>();
                    while (set2.next()) {
                        Visita v = new Visita();
                        v.setNome(set2.getString("nome"));
                        v.setCognome(set2.getString("cognome"));
                        DateTime h = new DateTime(set2.getTimestamp("data").toString());
                        v.setData(h.format("DD/MM/YYYY hh:mm:ss"));
                        l.add(v);
                    }
                    File txt = toTxt(l, id);
                    sendCapovillaggioMail(email, txt);
                    txt.delete();
                }


                String r = "SELECT DISTINCT pid,email FROM cartella "
                        + "JOIN paziente on cartella.pid = paziente.id "
                        + "WHERE  richiami != '0' "
                        + "AND is_fatta = 'F' "
                        + "AND data < '" + t + "';";
                set = JDBC.executeQuery(r, c);

                while (set.next()) {
                    int pid = set.getInt("pid");
                    String email = set.getString("email");
                    if (!email.equals("") && email != null) {
                        String q3 = "SELECT data,descrizione,tipo_visita,richiami "
                                + "FROM cartella WHERE richiami!='0' "
                                + "AND is_fatta = 'F' "
                                + "AND data < '" + t + "' "
                                + "and pid = " + pid;
                        ResultSet set2 = JDBC.executeQuery(q3, c);
                        LinkedList<String> l = new LinkedList<String>();
                        while (set2.next()) {
                            DateTime d = new DateTime(set2.getTimestamp("data").toString());
                            String s = "DATA: " + d.format("DD/MM/YYYY hh:mm:ss") + "\n"
                                    + "DESCRIZIONE: " + set2.getString("descrizione") + "\n"
                                    + "TIPO VISITA: " + set2.getString("tipo_visita") + "\n"
                                    + "NUMERO RICHIAMO: " + (set2.getInt("richiami")+1) + "\n";
                            l.add(s);
                        }
                        sendMailRichiami(email, l);
                    }
                }
            
                
                
                
                
                 r = "UPDATE cartella "
                        + "SET  richiami = richiami+1 "
                        + "WHERE  richiami != '0' "
                        + "AND is_fatta = 'F' "
                        + "AND data < '" + t + "';";

                JDBC.executeStatement(r, c);

            } catch (Exception ex) {
                error = true;
            } finally {
                try {
                    c.close();
                } catch (Exception ex) {
                }
            }
            if (!error) {
                setRenderRecidivi(false);
                setRenderTabellaRecidivi(false);
            }
        }
    }

    public List<Visita> listRichiami() {
        LinkedList<Visita> l = new LinkedList<Visita>();
        Connection c = null;
        try {
            Timestamp t = new Timestamp(System.currentTimeMillis() + (minuti * 60 * 1000));
            String r = "SELECT nome,cognome,data,tipo_visita "
                    + "FROM cartella JOIN anagrafe ON (cartella.pID = anagrafe.ID) "
                    + "WHERE  richiami = '0' "
                    + "AND is_fatta = 'F' "
                    + "AND data < '" + t + "';";
            c = JDBC.connect();
            ResultSet set = JDBC.executeQuery(r, c);
            while (set.next()) {
                Visita v = new Visita();
                v.setNome(set.getString("nome"));
                v.setCognome(set.getString("cognome"));
                v.setTipo(set.getString("tipo_visita"));

                DateTime h = new DateTime(set.getTimestamp("data").toString());
                v.setData(h.format("DD/MM/YYYY hh:mm:ss"));

                l.add(v);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                c.close();
            } catch (Exception ex) {
            }
        }
        if (l.isEmpty()) {
            listaRichiamaVuota = true;
        } else {
            listaRichiamaVuota = false;
        }
        return l;
    }

    public List<Visita> listReicidivi() {
        LinkedList<Visita> l = new LinkedList<Visita>();
        Connection c = null;
        try {
            Timestamp t = new Timestamp(System.currentTimeMillis() + (minuti * 60 * 1000));
            String r = "SELECT nome,cognome,data,tipo_visita,richiami "
                    + "FROM cartella JOIN anagrafe ON (cartella.pID = anagrafe.ID) "
                    + "WHERE  richiami != '0' "
                    + "AND is_fatta = 'F' "
                    + "AND data < '" + t + "';";
            c = JDBC.connect();
            ResultSet set = JDBC.executeQuery(r, c);
            while (set.next()) {
                Visita v = new Visita();
                v.setNome(set.getString("nome"));
                v.setCognome(set.getString("cognome"));
                v.setTipo(set.getString("tipo_visita"));
                v.setnRichiami(set.getInt("richiami"));
                DateTime h = new DateTime(set.getTimestamp("data").toString());
                v.setData(h.format("DD/MM/YYYY hh:mm:ss"));

                l.add(v);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                c.close();
            } catch (Exception ex) {
            }
        }
        if (l.isEmpty()) {
            listaRecidiciVuota = true;
        } else {
            listaRecidiciVuota = false;
        }
        return l;
    }

    private File toTxt(LinkedList<Visita> l, int id) throws Exception {
        OutputStreamWriter out = null;
        String webRoot = ((ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext()).getRealPath("/");
        try {

            out = new OutputStreamWriter(new FileOutputStream(webRoot + "richiami_" + id + ".txt"));
            int i = 0;
            while (!l.isEmpty()) {
                i++;
                Visita v = l.pop();
                out.write("Visita " + i + ":\t" + v.nome + "\t" + v.cognome + "\t\t" + v.data + "\n");
            }
        } finally {
            if (out != null) {
                out.close();
            }
        }
        return new File(webRoot + "richiami_" + id + ".txt");
    }

    //setter e getter
    public int getMinuti() {
        return minuti;
    }

    public void setMinuti(int minuti) {
        this.minuti = minuti;
    }

    public boolean isRenderRichiama() {
        return renderRichiama;
    }

    public void setRenderRichiama(boolean renderRichiama) {
        this.renderRichiama = renderRichiama;
    }

    public boolean isRenderRecidivi() {
        return renderRecidivi;
    }

    public void setRenderRecidivi(boolean renderRecidivi) {
        this.renderRecidivi = renderRecidivi;
    }

    public boolean isRenderTabellaRecidivi() {
        return renderTabellaRecidivi;
    }

    public void setRenderTabellaRecidivi(boolean renderTabellaRecidivi) {
        this.renderTabellaRecidivi = renderTabellaRecidivi;
    }

    public boolean isRenderTabellaRichiami() {
        return renderTabellaRichiami;
    }

    public void setRenderTabellaRichiami(boolean renderTabellaRichiami) {
        this.renderTabellaRichiami = renderTabellaRichiami;
    }

    public String getTastoRichiama() {
        return tastoRichiama;
    }

    public void setTastoRichiama(String tastoRichiama) {
        this.tastoRichiama = tastoRichiama;
    }

    public String getTastoRichiamaRecidivi() {
        return tastoRichiamaRecidivi;
    }

    public void setTastoRichiamaRecidivi(String tastoRichiamaRecidivi) {
        this.tastoRichiamaRecidivi = tastoRichiamaRecidivi;
    }

    /**
     * @return the listaRichiamaVuota
     */
    public boolean isListaRichiamaVuota() {
        return listaRichiamaVuota;
    }

    /**
     * @param listaRichiamaVuota the listaRichiamaVuota to set
     */
    public void setListaRichiamaVuota(boolean listaRichiamaVuota) {
        this.listaRichiamaVuota = listaRichiamaVuota;
    }

    /**
     * @return the listaRecidiciVuota
     */
    public boolean isListaRecidiciVuota() {
        return listaRecidiciVuota;
    }

    /**
     * @param listaRecidiciVuota the listaRecidiciVuota to set
     */
    public void setListaRecidiciVuota(boolean listaRecidiciVuota) {
        this.listaRecidiciVuota = listaRecidiciVuota;
    }

    public class Visita {

        private String nome;
        private String cognome;
        private String data;
        private String tipo;
        private int nRichiami;

        public String getNome() {
            return nome;
        }

        public void setNome(String nome) {
            this.nome = nome;
        }

        public String getCognome() {
            return cognome;
        }

        public void setCognome(String cognome) {
            this.cognome = cognome;
        }

        public String getData() {
            return data;
        }

        public void setData(String data) {
            this.data = data;
        }

        public String getTipo() {
            return tipo;
        }

        public void setTipo(String tipo) {
            this.tipo = tipo;
        }

        public int getnRichiami() {
            return nRichiami;
        }

        public void setnRichiami(int nRichiami) {
            this.nRichiami = nRichiami;
        }
    }
}
